
●
●
●
●
●
●
●
●
●
●
●
●
●
→ The JavaScript language → JavaScript Fundamentals
Functions
Quite often we need to perform a similar action in many places of the script.
For example, we need to show a nice-looking message when a visitor logs in, logs out and maybe somewhere
else.
Functions are the main “building blocks” of the program. They allow the code to be called many times without
repetition.
We’ve already seen examples of built-in functions, like alert(message) , prompt(message, default) and
confirm(question) . But we can create functions of our own as well.
To create a function we can use a function declaration.
It looks like this:
The function keyword goes first, then goes the name of the function, then a list of parameters between the
parentheses (empty in the example above) and finally the code of the function, also named “the function body”,
between curly braces.
Our new function can be called by its name: showMessage() .
For instance:
The call showMessage() executes the code of the function. Here we will see the message two times.
This example clearly demonstrates one of the main purposes of functions: to avoid code duplication.
If we ever need to change the message or the way it is shown, it’s enough to modify the code in one place: the
function which outputs it.
A variable declared inside a function is only visible inside that function.
For example:
A function can access an outer variable as well, for example:
The function has full access to the outer variable. It can modify it as well.
For instance:
The outer variable is only used if there’s no local one. So an occasional modification may happen if we forget
let .
If a same-named variable is declared inside the function then it shadows the outer one. For instance, in the code
below the function uses the local userName . The outer one is ignored:
Global variables
Variables declared outside of any function, such as the outer userName in the code above, are called
global.
Global variables are visible from any function (unless shadowed by locals).
Usually, a function declares all variables specific to its task. Global variables only store project-level data,
so when it’s important that these variables are accesible from anywhere. Modern code has few or no
globals. Most variables reside in their functions.
We can pass arbitrary data to functions using parameters (also called function arguments) .
In the example below, the function has two parameters: from and text .
When the function is called in lines (*) and (**) , the given values are copied to local variables from and
text . Then the function uses them.
Here’s one more example: we have a variable from and pass it to the function. Please note: the function changes
from , but the change is not seen outside, because a function always gets a copy of the value:
If a parameter is not provided, then its value becomes undefined .
For instance, the aforementioned function showMessage(from, text) can be called with a single argument:
That’s not an error. Such a call would output "Ann: undefined" . There’s no text , so it’s assumed that text
=== undefined .
If we want to use a “default” text in this case, then we can specify it after = :
Now if the text parameter is not passed, it will get the value "no text given"
Here "no text given" is a string, but it can be a more complex expression, which is only evaluated and
assigned if the parameter is missing. So, this is also possible:
Evaluation of default parameters
In JavaScript, a default parameter is evaluated every time the function is called without the respective
parameter. In the example above, anotherFunction() is called every time showMessage() is called
without the text parameter. This is in contrast to some other languages like Python, where any default
parameters are evaluated only once during the initial interpretation.
Default parameters old-style
Old editions of JavaScript did not support default parameters. So there are alternative ways to support
them, that you can find mostly in the old scripts.
For instance, an explicit check for being undefined :
…Or the || operator:
A function can return a value back into the calling code as the result.
The simplest example would be a function that sums two values:
The directive return can be in any place of the function. When the execution reaches it, the function stops, and
the value is returned to the calling code (assigned to result above).
There may be many occurrences of return in a single function. For instance:
It is possible to use return without a value. That causes the function to exit immediately.
For example:
In the code above, if checkAge(age) returns false , then showMovie won’t proceed to the alert .
A function with an empty return or without it returns undefined
If a function does not return a value, it is the same as if it returns undefined :
An empty return is also the same as return undefined :
⚠ Never add a newline between return and the value
For a long expression in return , it might be tempting to put it on a separate line, like this:
That doesn’t work, because JavaScript assumes a semicolon after return . That’ll work the same as:
So, it effectively becomes an empty return. We should put the value on the same line instead.
Functions are actions. So their name is usually a verb. It should be brief, as accurate as possible and describe
what the function does, so that someone reading the code gets an indication of what the function does.
It is a widespread practice to start a function with a verbal prefix which vaguely describes the action. There must
be an agreement within the team on the meaning of the prefixes.
For instance, functions that start with "show" usually show something.
Function starting with…
"get…" – return a value,
"calc…" – calculate something,
"create…" – create something,
"check…" – check something and return a boolean, etc.
Examples of such names:
With prefixes in place, a glance at a function name gives an understanding what kind of work it does and what
kind of value it returns.
One function – one action
A function should do exactly what is suggested by its name, no more.
Two independent actions usually deserve two functions, even if they are usually called together (in that
case we can make a 3rd function that calls those two).
A few examples of breaking this rule:
getAge – would be bad if it shows an alert with the age (should only get).
createForm – would be bad if it modifies the document, adding a form to it (should only create it
and return).
checkPermission – would be bad if it displays the access granted/denied message (should only
perform the check and return the result).
These examples assume common meanings of prefixes. What they mean for you is determined by you
and your team. Maybe it’s pretty normal for your code to behave differently. But you should have a firm
understanding of what a prefix means, what a prefixed function can and cannot do. All same-prefixed
functions should obey the rules. And the team should share the knowledge.
Ultrashort function names
Functions that are used very often sometimes have ultrashort names.
For example, the jQuery framework defines a function with $ . The LoDash library has its core function
named _ .
These are exceptions. Generally functions names should be concise and descriptive.
Functions should be short and do exactly one thing. If that thing is big, maybe it’s worth it to split the function
into a few smaller functions. Sometimes following this rule may not be that easy, but it’s definitely a good thing.
A separate function is not only easier to test and debug – its very existence is a great comment!
For instance, compare the two functions showPrimes(n) below. Each one outputs prime numbers up to n .
The first variant uses a label:
The second variant uses an additional function isPrime(n) to test for primality:
The second variant is easier to understand, isn’t it? Instead of the code piece we see a name of the action
( isPrime ). Sometimes people refer to such code as self-describing.
So, functions can be created even if we don’t intend to reuse them. They structure the code and make it readable.
A function declaration looks like this:
Values passed to a function as parameters are copied to its local variables.
A function may access outer variables. But it works only from inside out. The code outside of the function
doesn’t see its local variables.
A function can return a value. If it doesn’t, then its result is undefined .
To make the code clean and easy to understand, it’s recommended to use mainly local variables and parameters
in the function, not outer variables.
It is always easier to understand a function which gets parameters, works with them and returns a result than a
function which gets no parameters, but modifies outer variables as a side-effect.
Function naming:
A name should clearly describe what the function does. When we see a function call in the code, a good name
instantly gives us an understanding what it does and returns.
A function is an action, so function names are usually verbal.
There exist many well-known function prefixes like create… , show… , get… , check… and so on. Use them to
hint what a function does.
Functions are the main building blocks of scripts. Now we’ve covered the basics, so we actually can start creating
and using them. But that’s only the beginning of the path. We are going to return to them many times, going
more deeply into their advanced features.
importance: 4
The following function returns true if the parameter age is greater than 18 .
Otherwise it asks for a confirmation and returns its result:
Will the function work differently if else is removed?
Is there any difference in the behavior of these two variants?
solution
importance: 4
The following function returns true if the parameter age is greater than 18 .
Otherwise it asks for a confirmation and returns its result.
Rewrite it, to perform the same, but without if , in a single line.
Make two variants of checkAge :
1. Using a question mark operator ?
2. Using OR ||
solution
importance: 1
Write a function min(a,b) which returns the least of two numbers a and b .
For instance:
solution
importance: 4
Write a function pow(x,n) that returns x in power n . Or, in other words, multiplies x by itself n times and
returns the result.
Create a web-page that prompts for x and n , and then shows the result of pow(x,n) .
Run the demo
P.S. In this task the function should support only natural values of n : integers up from 1 .
solution
Function Declaration
function showMessage() {
alert( 'Hello everyone!' );
}
1
2
3
function showMessage() {
alert( 'Hello everyone!' );
}
showMessage();
showMessage();
1
2
3
4
5
6
Local variables
function showMessage() {
let message = "Hello, I'm JavaScript!"; // local variable
alert( message );
}
showMessage(); // Hello, I'm JavaScript!
alert( message ); // <-- Error! The variable is local to the function
1
2
3
4
5
6
7
8
9
Outer variables
let userName = 'John';
function showMessage() {
let message = 'Hello, ' + userName;
alert(message);
}
showMessage(); // Hello, John
1
2
3
4
5
6
7
8
let userName = 'John';
function showMessage() {
userName = "Bob"; // (1) changed the outer variable
let message = 'Hello, ' + userName;
alert(message);
}
alert( userName ); // John before the function call
showMessage();
alert( userName ); // Bob, the value was modified by the function
1
2
3
4
5
6
7
8
9
10
11
12
13
14
let userName = 'John';
function showMessage() {
let userName = "Bob"; // declare a local variable
let message = 'Hello, ' + userName; // Bob
alert(message);
}
// the function will create and use its own userName
showMessage();
alert( userName ); // John, unchanged, the function did not access the outer variable
1
2
3
4
5
6
7
8
9
10
11
12
13
Parameters
function showMessage(from, text) { // arguments: from, text
alert(from + ': ' + text);
}
showMessage('Ann', 'Hello!'); // Ann: Hello! (*)
showMessage('Ann', "What's up?"); // Ann: What's up? (**)
1
2
3
4
5
6
function showMessage(from, text) {
from = '*' + from + '*'; // make "from" look nicer
alert( from + ': ' + text );
}
let from = "Ann";
showMessage(from, "Hello"); // *Ann*: Hello
// the value of "from" is the same, the function modified a local copy
alert( from ); // Ann
1
2
3
4
5
6
7
8
9
10
11
12
13
Default values
function showMessage(from, text = "no text given") {
alert( from + ": " + text );
}
showMessage("Ann"); // Ann: no text given
1
2
3
4
5
function showMessage(from, text = anotherFunction()) {
// anotherFunction() only executed if no text given
// its result becomes the value of text
}
1
2
3
4
function showMessage(from, text) {
if (text === undefined) {
text = 'no text given';
}
alert( from + ": " + text );
}
1
2
3
4
5
6
7
function showMessage(from, text) {
// if text is falsy then text gets the "default" value
text = text || 'no text given';
...
}
1
2
3
4
5
Returning a value
function sum(a, b) {
return a + b;
}
let result = sum(1, 2);
alert( result ); // 3
1
2
3
4
5
6
function checkAge(age) {
if (age > 18) {
return true;
} else {
return confirm('Do you have permission from your parents?');
}
}
let age = prompt('How old are you?', 18);
if ( checkAge(age) ) {
alert( 'Access granted' );
} else {
alert( 'Access denied' );
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function showMovie(age) {
if ( !checkAge(age) ) {
return;
}
alert( "Showing you the movie" ); // (*)
// ...
}
1
2
3
4
5
6
7
8
function doNothing() { /* empty */ }
alert( doNothing() === undefined ); // true
1
2
3
function doNothing() {
return;
}
alert( doNothing() === undefined ); // true
1
2
3
4
5
return
(some + long + expression + or + whatever * f(a) + f(b))
1
2
return;
(some + long + expression + or + whatever * f(a) + f(b))
1
2
Naming a function
showMessage(..) // shows a message
getAge(..) // returns the age (gets it somehow)
calcSum(..) // calculates a sum and returns the result
createForm(..) // creates a form (and usually returns it)
checkPermission(..) // checks a permission, returns true/false
1
2
3
4
5
Functions == Comments
function showPrimes(n) {
nextPrime: for (let i = 2; i < n; i++) {
for (let j = 2; j < i; j++) {
if (i % j == 0) continue nextPrime;
}
alert( i ); // a prime
}
}
1
2
3
4
5
6
7
8
9
10
function showPrimes(n) {
for (let i = 2; i < n; i++) {
if (!isPrime(i)) continue;
alert(i); // a prime
}
}
function isPrime(n) {
for (let i = 2; i < n; i++) {
if ( n % i == 0) return false;
}
return true;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Summary
function name(parameters, delimited, by, comma) {
/* code */
}
1
2
3
✔ Tasks
Is "else" required?
function checkAge(age) {
if (age > 18) {
return true;
} else {
// ...
return confirm('Did parents allow you?');
}
}
1
2
3
4
5
6
7
8
function checkAge(age) {
if (age > 18) {
return true;
}
// ...
return confirm('Did parents allow you?');
}
1
2
3
4
5
6
7
Rewrite the function using '?' or '||'
function checkAge(age) {
if (age > 18) {
return true;
} else {
return confirm('Do you have your parents permission to access this page?');
}
}
1
2
3
4
5
6
7
Function min(a, b)
min(2, 5) == 2
min(3, -1) == -1
min(1, 1) == 1
1
2
3
Function pow(x,n)
pow(3, 2) = 3 * 3 = 9
pow(3, 3) = 3 * 3 * 3 = 27
pow(1, 100) = 1 * 1 * ...* 1 = 1
1
2
3
Comments
!
Chapter
JavaScript Fundamentals
Lesson navigation
Function Declaration
Local variables
Outer variables
Parameters
Default values
Returning a value
Naming a function
Functions == Comments
Summary
Tasks (4)
Comments
Share
Edit on Github
read this before commenting…
©2007—2019 Ilya Kantor | contact us | terms of usage | privacy policy | about the project
open source
EN
Tutorial Courses
👤
The tutorial was recently rewritten from scratch. There may be typos, please use the "Edit on Github" link (in left sidebar in an article, at the bottom) to propose fixes. Thank you!